/**
 * 
 */
package br.ufrgs.inf.cwsmart.recommendation;

import java.util.List;
import java.util.Map;

import javax.naming.OperationNotSupportedException;

import br.ufrgs.inf.cwsmart.CWSMartFramework;
import br.ufrgs.inf.cwsmart.core.CWSMart;
import br.ufrgs.inf.cwsmart.exception.FrameworkException;
import br.ufrgs.inf.cwsmart.util.Logger;

/**
 * Abstract recommendation class for a recommendation module that 
 * recommends a CWS to a mart in case the module is aware of the 
 * existence of another marts
 * 
 * @author Rodrigo S Lumertz
 *
 */
public abstract class Recommendation {

	/**
	 * The constructor automatically called by the class that implements the matcher 
	 */
	public Recommendation() {		
	}
	
	/**
	 * Comes into play following the failure of the matcher module. If this module 
	 * is not aware of the other CWSMarts then an "NOK" string is returned. In case 
	 * of positive recommendation return the id of CWSMart than can eventually accept 
	 * the CWS.
	 * 
	 * @param cwsFunctionalities The CWS functionalities
	 * @param cwsAttributes The CWS attributes
	 * 
	 * @return String with the possible values:
	 * "idCWSMart" in case a mart that can accept the CWS has been found
	 * "NOK" in case of no mart has been found
	 */
	public String RecommendCWSMart(List<String> cwsFunctionalities, 
			Map<String, String> cwsAttributes) {
		
		Logger.logger.log(Logger.INFORMATIONAL_LEVEL, "Recommendation.RecommendCWSMart", 
				"Recommending a CWSMart...");
		
		String result = "NOK"; 
		
		try {
			Logger.logger.log(Logger.DEBUG2_LEVEL, "Recommendation.RecommendCWSMart", "Getting the set of known CWSMarts");
			List<CWSMart> cwsMarts = this.getCWSMarts();
			
			for (CWSMart cwsMart : cwsMarts) {
				
				List<String> martTargetFunc = cwsMart.getCWSFunctionalities();				
				
				try {
					boolean isAccepted = CWSMartFramework.getInstance().getMatcherInstance().
						checkSemantic(cwsFunctionalities, martTargetFunc);
					
					if (isAccepted) {
						result = cwsMart.getIdCWSMart();
						break;
					}
				} catch (FrameworkException e) {
					// TODO: log and move forward
				}				
			}
			
		} catch (OperationNotSupportedException e) {
			// TODO: log and return
		}
		
		return result;
	}
	
	/**
	 * If the module is aware of the existence of others cwsmarts
	 * then return all of them. In case of not awareness throws an
	 * OperationNotSupportedException.
	 * 
	 * @return a List with all the cwsmarts
	 * @throws OperationNotSupportedException
	 */
	protected abstract List<CWSMart> getCWSMarts()
		throws OperationNotSupportedException;
}
